package 会话对象持久化;

import java.io.*;
import java.time.LocalDateTime;
import java.util.*;

public class 会话对象持久化
{

    // 1. User类（需要序列化）
    public static class User implements Serializable {
        private String userId;
        private String username;

        public User(String userId, String username) {
            this.userId = userId;
            this.username = username;
        }

        public String getUserId() {
            return userId;
        }

        public String getUsername() {
            return username;
        }

        @Override
        public String toString() {
            return "User{" +
                    "userId='" + userId + '\'' +
                    ", username='" + username + '\'' +
                    '}';
        }
    }

    // 2. UserSession类（实现Serializable）
    public static class UserSession implements Serializable {
        private String sessionId;
        private User user;
        private LocalDateTime expireTime;

        public UserSession(String sessionId, User user, LocalDateTime expireTime) {
            this.sessionId = sessionId;
            this.user = user;
            this.expireTime = expireTime;
        }

        public String getSessionId() {
            return sessionId;
        }

        public User getUser() {
            return user;
        }

        public LocalDateTime getExpireTime() {
            return expireTime;
        }

        @Override
        public String toString() {
            return "UserSession{" +
                    "sessionId='" + sessionId + '\'' +
                    ", user=" + user +
                    ", expireTime=" + expireTime +
                    '}';
        }
    }

    // 3. 模拟的Redis客户端：使用Map模拟存储
    public static class RedisClient {
        private final Map<String, byte[]> storage = new HashMap<>();

        public void set(String key, byte[] value) {
            storage.put(key, value);
        }

        public byte[] get(String key) {
            return storage.get(key);
        }
    }

    // 4. 主程序逻辑
    public static void main(String[] args) throws Exception {
        // 初始化Redis客户端（模拟）
        RedisClient redisClient = new RedisClient();

        // 创建用户对象
        User user = new User("U001", "Alice");

        // 创建会话对象
        LocalDateTime expireTime = LocalDateTime.now().plusHours(1);
        UserSession session = new UserSession("SESSION_001", user, expireTime);

        // 模拟保存会话到Redis
        saveSession(session, redisClient);

        // 模拟从Redis加载会话
        UserSession loadedSession = loadSession("SESSION_001", redisClient);

        // 输出结果
        System.out.println("Loaded Session: " + loadedSession);
        System.out.println("User in Session: " + loadedSession.getUser());
    }

    // 5. 保存会话到Redis（模拟）
    public static void saveSession(UserSession session, RedisClient redisClient) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(bos)) {
            oos.writeObject(session);
            redisClient.set(session.getSessionId(), bos.toByteArray());
        }
    }

    // 6. 从Redis恢复会话
    public static UserSession loadSession(String sessionId, RedisClient redisClient) throws IOException, ClassNotFoundException {
        byte[] data = redisClient.get(sessionId);
        if (data == null)
        {
            return null;
        }

        try (ByteArrayInputStream bis = new ByteArrayInputStream(data);
             ObjectInputStream ois = new ObjectInputStream(bis)) {
            return (UserSession) ois.readObject();
        }
    }
}